package com.hopedove.tempdemo.utils

import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Rect
import kotlin.math.max

data class Cell(val x: Int, val y: Int)

fun generateBitmap(
    rows: Int,
    columns: Int,
    cells: List<Cell>,
    content: Bitmap,
    bottomIndicate: Boolean = false,
    rightIndicate: Boolean = false,
    padding: Int = 1,
    border: Int = 1
): Bitmap {
    val bmpContent = resizeBitmapToSquare(content)
    val cellSize = bmpContent.width
    val rowCount = if (bottomIndicate) rows + 1 else rows
    val columnCount = if (rightIndicate) columns + 1 else columns
    val container = generateBigContainer(rowCount, columnCount, cellSize, padding, border)

    cells.forEach {
        drawImage(it, content, padding, border, container)
    }

    return container
}

private fun drawImage(cell: Cell, content: Bitmap, padding: Int, border: Int, container: Bitmap) {
    val canvas = Canvas(container)
    val cellSize = content.width + 2 * border
    val dstWidthBorder = Rect(0, 0, cellSize, cellSize)
    dstWidthBorder.offset(padding, padding)
    val dx = cell.x * cellSize
    val dy = cell.y * cellSize
    dstWidthBorder.offset(dx, dy)

    val dst = Rect(
        dstWidthBorder.left - border,
        dstWidthBorder.top - border,
        dstWidthBorder.right - border,
        dstWidthBorder.bottom - border
    )
    canvas.drawBitmap(content, null, dst, null)
}

private fun drawText(
    cell: Cell,
    number: Int,
    size: Int,
    padding: Int,
    border: Int,
    container: Bitmap
) {
    val content = number.toString()
    val canvas = Canvas(container)
    val cellSize = size + 2 * border
    val dstWidthBorder = Rect(0, 0, cellSize, cellSize)
    dstWidthBorder.offset(padding, padding)
    val dx = cell.x * cellSize
    val dy = cell.y * cellSize
    dstWidthBorder.offset(dx, dy)

    val paint = Paint().apply {
        textSize = 10F
        isAntiAlias = true
        isDither = true
    }
    val bounds = Rect()
    paint.getTextBounds(content, 0, content.length, bounds)

    val dst = Rect(
        dstWidthBorder.left - border,
        dstWidthBorder.top - border,
        dstWidthBorder.right - border,
        dstWidthBorder.bottom - border
    )

    bounds.offsetTo(dst.left, dst.top)
    val ddx = (dst.width() - bounds.width()) / 2
    val ddy = (dst.height() - bounds.height()) / 2
    bounds.offset(ddx, ddy)

    canvas.drawText(content, bounds.left.toFloat(), bounds.bottom.toFloat(), paint)
}

private fun generateBigContainer(
    rows: Int,
    columns: Int,
    size: Int,
    padding: Int,
    border: Int
): Bitmap {
    val cellSize = size + 2 * border
    val width = cellSize * columns + 2 * padding
    val height = cellSize * rows + 2 * padding
    return Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
}

private fun resizeBitmapToSquare(origin: Bitmap): Bitmap {
    if (origin.width == origin.height) return origin

    val size = max(origin.width, origin.height)
    val newBmp = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888)

    val dst = Rect(0, 0, origin.width, origin.height)
    val dx = (size - dst.width()) / 2
    val dy = (size - dst.height()) / 2
    dst.offset(dx, dy)

    Canvas(newBmp).apply {
        drawBitmap(origin, null, dst, null)
    }
    return newBmp
}